var _service = angular.module('services', []);

_service.constant('dbConfig',{
    dbName: 'paulo',
    dbServer: 'http://myCouchServerIp:5984/'
});

/**
 * Make PouchDB available in AngularJS.
 */
_service.factory('$db', ['dbConfig', function(dbConfig) {
    PouchDB.enableAllDbs = true;
    var localDb = new PouchDB(dbConfig.dbName);
    var remoteDb = dbConfig.dbServer + dbConfig.dbName;
    var options = {live: true};
    var syncError = function() {
        console.log('Problem encountered during database synchronisation');
    };

    console.log('Replicating from local to server');
    localDb.replicate.to(remoteDb, options, syncError);

    console.log('Replicating from server back to local');
    localDb.replicate.from(remoteDb, options, syncError);   

    return localDb; 
}]);

_service.factory('Machine', ['$q', '$db', '$rootScope', 'dbConfig', 
                   function($q, $db, $rootScope, dbConfig) {
    return {
        update: function(machine)  {
            var delay = $q.defer();

            var doc = {
               _id: machine._id,
               _rev: machine._rev,
               type: machine.type,
               customer: machine.customer,
               factory: machine.factory,
               lineId: machine.lineId,
               plcVersion: machine.plcVersion,
               dateCreated: machine.dateCreated,
               lastUpdated: new Date().toUTCString()
            };

            $db.put(doc, function(error, response) {
                $rootScope.$apply(function() {
                    if (error) {
                        console.log('Update failed: ');
                        console.log(error);
                        delay.reject(error);
                    } else {
                        console.log('Update succeeded: ');
                        console.log(response);
                        delay.resolve(response);
                    }
                });
            });

            return delay.promise;
        },
        getAll: function() {
            var delay = $q.defer();

            var map = function(doc) {
                if (doc.type === 'machine') {
                    emit([doc.customer, doc.factory], 
                            {
                                _id: doc._id,
                                customer: doc.customer, 
                                factory: doc.factory,
                                lineId: doc.lineId, 
                                plcVersion: doc.plcVersion,
                            }
                    );
                }
            };

            $db.query({map: map}, function(error, response) {
                $rootScope.$apply(function() {
                    if (error) {
                        delay.reject(error);
                    } else {
                        console.log('Query retrieved ' + response.rows.length + ' rows');
                        var queryResults = [];

                        // Create an array from the response 
                        response.rows.forEach(function(row) {
                            queryResults.push(row.value);
                        });

                        delay.resolve(queryResults);
                    }
                });
            });

            return delay.promise;
        },
        sync: function() {
            var remoteDb = dbConfig.dbServer + dbConfig.dbName;
            var options = {live: true};
            var syncError = function(error, changes) {
                console.log('Problem encountered during database synchronisation');
                console.log(error);
                console.log(changes);
            };
            var syncSuccess = function(error, changes) {
                console.log('Sync success');
                console.log(error);
                console.log(changes);
            };

            console.log('Replicating from local to server');
            $db.replicate.to(remoteDb, options, syncError).
                on('error', syncError).
                on('complete', syncSuccess);

            console.log('Replicating from server back to local');
            $db.replicate.from(remoteDb, options, syncError);       
        }
    };
}]);

_service.factory('dbListener', ['$rootScope', '$db', function($rootScope, $db) {
    console.log('Registering a onChange listener');
    $db.info(function(error, response) {
        $db.changes({
            since: response.update_seq,
            live: true,
        }).on('change', function() {
            console.log('Change detected by the dbListener');
            // TODO work out why this never happens
        });
    });
}]);